﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WordNet.Core;
using WordNet.Core.DataContract;
using WordNet.Core.ElementContracts;

namespace Parsers
{
    [Export(typeof(IParser<IIndexWord>))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class IndexLineParser:IParser<IIndexWord>
    {
        private IndexLineParser()
        { }
        
        public IIndexWord Parse(string line)
        {
            if (line == null)
                throw new ArgumentNullException();
            int index = 0;
            string[] tokens = line.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            Builder builder = new Builder();
            builder.AddLemma(tokens[index++])// get lemma
                    .AddPos(tokens[index++]);
            // skiping synset counter
            index++;

            // get number of pointers
            int p_cnt = int.Parse(tokens[index++]);
            // get pointer symbols
            for (int i = 0; i < p_cnt; i++)
            {
                builder.AddPointer(tokens[index++]);
            }

            int senseCount = int.Parse(tokens[index++]);
            builder.AddTagCount(tokens[index++]);

            // int offset;
            for (int i = 0; i < senseCount; i++)
            {
                builder.AddOffsets(tokens[index++]);
            }

            return builder.Build();
        }


        private class Builder
        {
            List<IPointer> pointers = new List<IPointer>();
            List<IWordID> offsets = new List<IWordID>();
            POS _pos;
            string cnt;
            string lemma;
            public Builder() { }

            public Builder AddTagCount(string cnt)
            {
                this.cnt = cnt;
                return this;
            }
            public Builder AddLemma(string lemma)
            {
                this.lemma = lemma;
                return this;
            }
            public Builder AddPos(string pos)
            {
                _pos = POS.GetPartOfSpeech(pos[0]);
                return this;
            }
            public Builder AddPointer(string p)
            {
                pointers.Add(Pointer.GetPointerType(p, _pos));
                return this;
            }
            public Builder AddOffsets(string o)
            {
                offsets.Add(new WordID(new SynsetID(int.Parse(o), _pos), lemma));
                return this;
            }

            public IIndexWord Build()
            {
                return new IndexWord(lemma, _pos, int.Parse(cnt), pointers.ToArray(), offsets.ToArray());
            }

        }
    }
}
